﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Http;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using Extentions;
using TrainingReminderSystem.Model;
using TrainingReminderSystem.Dal;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Controllers;

namespace TrainingReminderSystem.Bll
{
    /// <summary>
    /// 用户操作日志 逻辑层
    /// </summary>
    public partial class SysOperateLogBll : PcLoginedBll
    {
        public static string GetUrl(ActionExecutingContext context)
        {
            var controllerActionDescriptor = (ControllerActionDescriptor)context.ActionDescriptor;
            string currentUrl = controllerActionDescriptor.AttributeRouteInfo?.Template;
            if (string.IsNullOrEmpty(currentUrl))
            {
                string action = context.ActionDescriptor.RouteValues["action"];
                string controller = context.ActionDescriptor.RouteValues["controller"];
                currentUrl = $"api/{controller}/{action}";
            }
            else
            {
                if (currentUrl.IndexOf("/", StringComparison.Ordinal) == 0)
                {
                    currentUrl = currentUrl.Substring(1);
                }
            }
            return currentUrl;
        }

        /// <summary>
        /// 处理日志
        /// </summary>
        /// <param name="context"></param>
        /// <param name="tempAr"></param>
        /// <param name="isError"></param>
        public static void DealSysOperateLog(ActionExecutingContext context, bool isError, AjaxResult tempAr)
        {
            ControllerActionDescriptor controllerActionDescriptor = (ControllerActionDescriptor)context.ActionDescriptor;
            Type type = typeof(ExOperateLogAttribute);
            object[] arr = controllerActionDescriptor.MethodInfo.GetCustomAttributes(type, false);
            if (arr == null || arr.Length == 0) return;
            ExOperateLogAttribute attr = arr[0] as ExOperateLogAttribute;
            if (attr == null) return;

            string currentUrl = SysOperateLogBll.GetUrl(context);
            if (attr.EnumOperateLogType == EnumOperateLogType.登录)
            {
                AjaxResult<List<LoginInfo>> ar = tempAr as AjaxResult<List<LoginInfo>>;
                if (ar == null) return;
                foreach (var item in ar.Result)
                {
                    SysOperateLog tempModel = GetSysOperateLog(context, isError, currentUrl, attr);
                    if (tempModel == null) continue;
                    tempModel.SysEmployeeID = item.SysEmployeeID;
                    tempModel.SysStoreID = item.SysStoreID;
                    TaskRunAdd(tempModel);
                }
                return;
            }
            if (attr.EnumOperateLogType == EnumOperateLogType.注销)
            {
                AjaxResult<SysEmployeeBll.LoginOutResult> ar = tempAr as AjaxResult<SysEmployeeBll.LoginOutResult>;
                if (ar == null) return;
                SysOperateLog tempModel = GetSysOperateLog(context, isError, currentUrl, attr);
                if (tempModel == null) return;
                SysEmployeeBll.LoginOutResult item = ar.Result;
                if (item == null) return;
                tempModel.SysEmployeeID = item.SysEmployeeID;
                tempModel.SysStoreID = item.SysStoreID;
                TaskRunAdd(tempModel);
                return;
            }

            SysOperateLog model = GetSysOperateLog(context, isError, currentUrl, attr);
            if (model == null) return;
            TaskRunAdd(model);
        }

        private static void TaskRunAdd(SysOperateLog model)
        {
            SysOperateLogBll bll = new SysOperateLogBll();
            Task.Run(async () =>
            {
                try
                {
                    await bll.Add(model);
                }
                catch (Exception ex)
                {
                    ex.ExLogError("记录日志报错");
                }
            });
        }

        private static SysOperateLog GetSysOperateLog(ActionExecutingContext context, bool isError, string currentUrl, ExOperateLogAttribute attr)
        {
            int sysStoreID = CurrentStore?.SysStoreID ?? 0;
            var list = new List<EnumOperateLogType>()
            {
                  EnumOperateLogType.登录,
                  EnumOperateLogType.注销
            };
            if (sysStoreID == 0 && list.Contains(attr.EnumOperateLogType) == false)
            {
                return null;
            }
            SysOperateLog model = new SysOperateLog()
            {
                IsError = isError,
                CreateDate = DateTime.Now,
                SysCustomerID = null,
                EnumOperateLogType = attr.EnumOperateLogType,
                GetUrl = currentUrl,
                ID = 0,
                IPAddress = ToolHelper.GetIpAddress(),
                PostForm = context.HttpContext?.Request?.ExBodyString() ?? string.Empty,
                Remark = null,
                SysEmployee = null,
                SysEmployeeID = CurrentEmployee?.SysEmployeeID,
                SysStore = null,
                SysStoreID = sysStoreID,
                UserAgent = context.HttpContext?.Request?.UserAgent() ?? string.Empty
            };
            return model;
        }
    }
}
